window.ViewActionType = {
    None: 0,
    Scale: 1
};

window.ViewTag = {
    View: 0,
    Board: 1,
    Window: 2
};


/**
 * 显示基类
 */
var View = cc.Node.extendEX({
    // 动画类型
    _actionType: ViewActionType.None,

    viewTag: ViewTag.View,
    /**
     * 禁止的node名字
     * @private
     * @type {Array}
     */
    _banName: [
        'name',
        'parent',
        'tag',
        'children'
    ],

    /**
     * ccs缓存池对象上限
     * @private
     * @type {Number}
     * @const
     */
    capacityMax: 999,

    /**
     * ccs文件路径
     * @protected
     * @type {String}
     */
    _ccsFileName: null,

    /**
     * ccs根节点
     * @protected
     * @type {cc.Node}
     */
    _rootNode: null,

    /**
     * ccs动作
     * @protected
     * @type {cc.Action}
     */
    _rootAction: null,

    /**
     * ccs子节点列表
     * @public
     * @type {Object}
     */
    _nodeList: {},

    /**
     * 是否添加阻止layer
     * @protected
     * @type {Boolean}
     */
    _blockBack: false,
    /**
     * 是否添加阻止layer
     * @protected
     * @type {ccui.Layout}
     */
    _blockLayer: null,
    /**
     * 背景层颜色
     * @protected
     * @type {cc.Color}
     */
    _blockLayerColor: cc.color('#000000'),

    /**
     * 背景层透明度
     * @protected
     * @type {Number}
     */
    _blockLayerOpacity: 255 * 0.7,

    /**
     * 点击阻止layer是否关闭界面
     * @protected
     * @type {Boolean}
     */
    _notCloseBlock: false,

    /**
     * 网络监听
     * @protected
     * @type {Object}
     */
    _networkListeners: {},

    /**
     * 网络监听
     * @protected
     * @type {Object}
     */
    _clickListeners: {},

    /**
     *  事件监听
     *  @protected
     *  @type {Object}
     */
    _eventListeners: {},

    /**
     * ccs资源是否加载完毕
     * @protected
     * @type {boolean}
     */
    _loadCCSFinished: false,

    /**
     * 显示数据
     * @protected
     * @type {*}
     */
    _viewData: null,
    ctor: function () {
        cc.Node.prototype.ctor.call(this);
        cc.log(this._ccsFileName);
        if(!this._ccsFileName){
            this._rootNode = new cc.Node();
            this.addChild(this._rootNode);
            return;
        }
        this._loadCCS();
        this._initBlockLayer();
        this._nodeList = {};
        this._resolveCCS(this._rootNode);
        this._addAllUnit();
    },
    /**
     * View基类初始化
     */
    initView: function () {
        this._actionType = ViewActionType.None;
        if (this._actionType === ViewActionType.None) {
            this._rootNode.show();
        }
        this._loadCCSFinished = true;
        this._initAllListeners();
        this.setData.apply(this, arguments);
    },

    /**
     * 使用 _ccsFileName 加载ccs文件
     * @protected
     */
    _loadCCS: function () {
        if (isNullString(this._ccsFileName)) {
            cc.error('初始化加载_ccsFileName为空');
            return;
        }
        var ccsObj = this._getCCSCache(this._ccsFileName);
        if (!ccsObj) {
            var resPath = getCCSFileNamePath(this._ccsFileName);
            ccsObj = ccs.load(this._ccsFileName, resPath);
            setDesignResolution(ccsObj.node);
            this._addCCSCache(this._ccsFileName, ccsObj);
        }
        this._loadCCSFinished = false;
        this._rootNode = duplicateNode(ccsObj.node);
        this._rootAction = ccsObj.action;
        this.addChild(this._rootNode);
        this._rootNode.hide();
    },

    /**
     * 添加ccs缓存
     * @private
     * @param  {String} fileName
     * @param {{node: cc.Node, action: cc.Action}} ccsObj
     */
    _addCCSCache: function (fileName, ccsObj) {
        window['view_ccs_cache'] = window['view_ccs_cache'] || [];
        var cahce = window['view_ccs_cache'];

        //如果cahce超过最大上限
        if (cahce.length >= this.capacityMax) {
            var removeElement = cahce.shift();
            var removeObj = removeElement.ccsObj;
            removeObj.node.release();
        }
        ccsObj.node.retain();
        cahce.push({'name': fileName, 'ccsObj': ccsObj});
        cc.log("添加缓存CCS == "+ fileName);
    },

    /**
     * 获取ccs对象缓存池
     * @private
     * @param  {String} fileName
     * @returns {{node: cc.Node, action: cc.Action}} ccsObj
     */
    _getCCSCache: function (fileName) {
        window['view_ccs_cache'] = window['view_ccs_cache'] || [];
        var cahce = window['view_ccs_cache'];
        var ccsObj = null;
        _.forIn(cahce, function (obj) {
            if (obj.name == fileName) {
                ccsObj = obj.ccsObj;
            }
        });
        return ccsObj;
    },

    /**
     * 检测所有的node是否加载完毕
     * @private
     */
    _checkAllNodeValid: function () {
        if (this._checkNodeValid(this._rootNode)) {
            this.unschedule(this._checkAllNodeValid);
            this._onCCSLoadFinish();
        }
    },

    /**
     * 检查是否转屏完毕
     * @private
     */
    _checkSceneTransitionOver: function () {
        if (window.sceneStack.length == 1) {
            this._onSceneTransitionOver();
            this.unschedule(this._checkSceneTransitionOver);
        }
    },

    /**
     * 转屏完毕
     * @protected
     */
    _onSceneTransitionOver: function () {

    },

    /**
     * 检测子node是否有效
     * @param node
     * @private
     */
    _checkNodeValid: function (node) {
        if (!cc.sys.isObjectValid(node))
            return false;
        var children = node.getChildren();
        if (children.length) {
            for (var i = 0; i < children.length; i++)
                if (!this._checkNodeValid(children[i]))
                    return false;
        }
        return true;
    },

    /**
     * 加载ccs资源完成回调
     * @protected
     */
    _onCCSLoadFinish: function () {
        this._nodeList = {};
        this._resolveCCS(this._rootNode);
        this._initAllListeners();
        this._addAllUnit();
        this._rootNode.show();
        this._loadCCSFinished = true;
        // this._refreshData(this._viewData);
        this._refreshData.apply(this, this._viewData);
    },

    /**
     * 解析ccs
     * 同名同结构会发生覆盖现象
     * @param {cc.Node} node 要解析的节点
     * @param {String} [root] 上溯节点名
     * @protected
     */
    _resolveCCS: function (node, root) {
        var self = this;
        if (!node) {
            return;
        }
        var name = null;
        var memberPrefix = '_';
        if (node != this._rootNode) {
            name = node.getName();
            if (this._banName.indexOf(name) >= 0) {
                cc.error('ccs:' + this._ccsFileName + ' 中含有名为:' + name);
                return;
            }
            if (root) {
                name = root + '.' + name;
            }
            this._nodeList[name] = node;

            /**
             * 以'_'开头的节点全部记录在跟节点，重名会覆盖
             */
            var widgetName = node.getName();
            widgetName = widgetName.trim();
            // 控件名存在，绑定到target上
            var prefix = widgetName.substr(0, memberPrefix.length);
            if (prefix === memberPrefix) {
                this._nodeList[widgetName] = node;
            }
        }
        var childlist = node.getChildren();
        _.forIn(childlist, function (child) {
            node[child.getName()] = child;
            self._resolveCCS(child, name);
        });
    },

    /**
     * 执行ccs动作
     * @publis
     * @param {Boolean} [loop] 是否循环
     */
    runCCSAction: function (loop) {
        if (!this._rootNode) {
            return;
        }
        if (!this._rootAction) {
            return;
        }
        this._rootNode.runAction(this._rootAction);
        this._rootAction.play('action', loop);
    },

    /**
     * 初始化阻止layer和阻止bg
     * @private
     */
    _initBlockLayer: function () {
        var self = this;
        if (!this._blockBack) {
            return;
        }
        self._blockLayer = new ccui.Layout();
        self._blockLayer.setContentSize(cc.winSize);
        self._blockLayer.setBackGroundColorType(ccui.Layout.BG_COLOR_SOLID);
        self._blockLayer.setBackGroundColor(this._blockLayerColor);
        self._blockLayer.setBackGroundColorOpacity(this._blockLayerOpacity);
        this.addChild(self._blockLayer, -1);
        TouchUtil.setOnclickListener(self._blockLayer, function () {
            if (!self._notCloseBlock) {
                self.removeFromParent(true);
            }
        }, {effect: TouchUtil.effects.NONE});

        var bg = this._nodeList['bg'];
        if (!bg) {
            return;
        }
        TouchUtil.setOnclickListener(bg, function () {
        }, {effect: TouchUtil.effects.NONE});
    },

    /**
     * 初始化所有事件
     * @private
     */
    _initAllListeners: function () {
        this._initClickListeners();
        this._initNetworkListeners();
        this._initEventListeners();

        this._addClickListeners();
        this._addNetworkListeners();
        this._addEventListeners();
    },

    /**
     * 初始化触摸事件
     * @protected
     */
    _initClickListeners: function () {
        this._clickListeners = {};
    },

    /**
     * 初始化网络监听事件
     * @protected
     */
    _initNetworkListeners: function () {
        this._networkListeners = {};
    },

    /**
     * 初始化事件监听
     * @protected
     */
    _initEventListeners: function () {
        this._eventListeners = {};
    },

    /**
     * 添加事件
     * @protected
     */
    _addEventListener: function (key, callback) {
        eventManager.addListener(key, callback, this);
    },

    /**
     * 添加监听事件
     * @private
     */
    _addEventListeners: function () {
        var self = this;
        _.forIn(self._eventListeners, function (callback, key) {
            if (!_.isString(callback) || !_.isFunction(self[callback])) {
                cc.error('没有该listener: ' + callback);
                return;
            }
            self._addEventListener(key, self[callback].bind(self));
        });
    },

    /**
     * 添加点击监听事件(支持sprite和button)
     * @private
     */
    _addClickListeners: function () {
        var self = this;
        _.forIn(self._clickListeners, function (listener, nodeName) {
            self._addClickListener(nodeName, listener);
        });
    },

    /**
     * 添加点击事件(支持sprite和button)
     * @param {String} nodeName
     * @param {String} listener
     * @protected
     */
    _addClickListener: function (nodeName, listener) {
        var node = this._nodeList[nodeName];
        if (!node || !(node instanceof cc.Node) || !node.isValid()) {
            return;
        }
        if (!_.isString(listener) || !_.isFunction(this[listener])) {
            return;
        }
        if (node instanceof ccui.Button) {
            node.addClickEventListener(this[listener].bind(this));
        } else {
            TouchUtil.setOnclickListener(node, this[listener].bind(this));
        }
    },

    /**
     * 添加网络监听
     * @private
     */
    _addNetworkListeners: function () {
        var self = this;
        _.forIn(self._networkListeners, function (listener, code) {
            self._addNetworkListener(code, listener);
        });
    },

    /**
     * 添加网络监听
     * @param {Number} code
     * @param {Function} listener
     * @protected
     */
    _addNetworkListener: function (code, listener) {
        if (!_.isString(listener) || !_.isFunction(this[listener])) {
            cc.error('没有该listener: ' + listener);
            return;
        }
        if (!P[code] && !MsgCode[code]) {
            cc.error('没有该code: ' + code);
        }
        var key = 'Net_';
        if (_.startsWith(code, 'GS')) {
            key = 'GS_' + key + P[code];
        } else {
            key = 'Msg_' + key + MsgCode[code];
        }
        this._addEventListener(key, this[listener].bind(this));
    },

    /**
     * 添加所有的unit
     * @private
     */
    _addAllUnit: function () {
        var self = this;
        _.forIn(this._nodeList, function (node, name) {
            var lastname = _.last(name.split('.'));
            if (_.startsWith(lastname, 'unit_')) {
                self._addUnit(node);
            }
        });
    },
    /**
     * 添加组件
     * @private
     */
    _addUnit: function (node) {
        var name = node.getName();
        var names = name.split('_');
        if (names.length < 2) {
            return;
        }
        names = _.drop(names);
        name = names.join('_');
        addUnit(name, node);
    },

    /**
     * 删除全部事件监听
     * @protected
     */
    _removeAllEventListener: function () {
        eventManager.removeListeners(this);
    },

    /**
     * 刷新界面数据
     * @protected
     */
    _refreshData: function () {

    },

    /**
     * 公开的刷新界面数据
     * @public
     */
    setData: function () {
        this._viewData = arguments;
        if (!this._loadCCSFinished) {
            return;
        }
        this._refreshData.apply(this, arguments);
    },

    /**
     * 关闭界面
     * @public
     */
    close: function () {
        if (this.isValid()) {
            this.removeFromParent(true);
        }
    },

    /**
     * 退出处理
     */
    onExit: function () {
        // this._removeAllEventListener();
        cc.Node.prototype.onExit.call(this);
    },

    /**
     * 退出开始执行动画时处理
     */
    onExitTransitionDidStart: function () {
        this._removeAllEventListener();
        cc.Node.prototype.onExitTransitionDidStart.call(this);
    },

    onEnterTransitionDidFinish: function () {
        cc.Node.prototype.onEnterTransitionDidFinish.call(this);
        this._showAction();
    },

    _showAction: function () {
        if (!this._rootNode) {
            return;
        }
        if (this._rootNode.isVisible()) {
            return;
        }
        this._rootNode.show();
        if (this._actionType === ViewActionType.Scale) {
            this._rootNode.setScale(0.7);
            this._rootNode.runAction(cc.scaleTo(0.2, 1, 1)).easing(cc.easeBackOut());
        }
    }
});